package ru.urfc.portal.rest;

import java.io.StringWriter;
import java.io.Writer;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import ru.urfc.portal.dao.filter.Filter;
import ru.urfc.portal.managers.DocumentManager;
import ru.urfc.portal.model.audit.AuditLogEntry;
import ru.urfc.portal.model.documents.Document;
import ru.urfc.portal.model.documents.DocumentCreate;
import ru.urfc.portal.model.documents.DocumentStateChange;
import ru.urfc.portal.model.documents.DocumentUpdate;
import ru.urfc.portal.model.radio.DeviceWithNet;
import ru.urfc.portal.operations.DocumentContentService;
import ru.urfc.portal.ui.client.Constants;

@Stateless
@Produces({MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
@Path(Constants.CLIENTS + "/{clientId}/" + Constants.DOCUMENTS)
public class DocumentService extends BaseService {

	@EJB DocumentManager documentManager;
	@EJB DocumentContentService documentContentService;
	@EJB AttachedFilesService attachedFilesService;
	
	private static final String CLIENT_ID = "clientId";  
	private static final String DOCUMENT_ID = "documentId";  
	
	@GET
	public List<Document> listDocuments(@PathParam(CLIENT_ID) Long clientId, @Context HttpServletRequest request) {
		Filter filter = new Filter();
		filter.addEqual("type.code", getStr(FILTER_DOCUMENT_TYPE_CODE, request));
		filter.addEqual("state.code", getStr(FILTER_DOCUMENT_STATE_CODE, request));
		return documentManager.getClientDocuments(clientId, filter);
	}
	
	@POST
	@Produces(MediaType.TEXT_PLAIN)
	public String createDocument(@PathParam(CLIENT_ID) Long clientId, DocumentCreate documentCreate) {
		return documentManager.createDocument(clientId, documentCreate).getId().toString();
	}

	@Path("{" + DOCUMENT_ID + "}")
	public SubService getSubService() {
		return new SubService(); 
	}
	
	public class SubService {
			
		@GET
		public Document getDocument(@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId) {
			return documentManager.getDocument(clientId, documentId);
		}
		
		@GET
		@Path("xml")
		public Document xml(@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId) {
			return documentManager.getDocumentWithSelectedDevices(documentId).check(clientId);
		}

		@PUT
		public Document updateDocument(@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId,
				DocumentUpdate documentUpdate) {
			return documentManager.upadteDocument(clientId, documentId, documentUpdate);
		}	
	
		@GET
		@Path(DOCUMENT_SELECTED_DEVICES)
		public List<DeviceWithNet> listDevices(@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId) {
			return documentManager.getSelectedDevices(clientId, documentId);
		}
		
		@POST
		@Path(DOCUMENT_SUBMIT)
		public Document submit(@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId,
				DocumentUpdate documentUpdate) {
			Document document = documentManager.updateAndSubmitDocument(clientId, documentId, documentUpdate);
			return document;			
		}
	
		@GET
		@Path(DOCUMENT_STATE_CHANGES)
		public List<DocumentStateChange> listStateHistory(@PathParam(CLIENT_ID) Long clientId,
				@PathParam(DOCUMENT_ID) Long documentId) {
			return documentManager.getDocumentStateChanges(clientId, documentId);
		}
		
		@GET
		@Path("audit-log")
		public List<AuditLogEntry> listAuditLog(@PathParam(CLIENT_ID) Long clientId,
				@PathParam(DOCUMENT_ID) Long documentId) {
			return new ClientService().getSubService().listAuditLog(clientId);
		}
		
		@GET
		@Path(DOCUMENT_PRINT)
		@Produces(MediaType.TEXT_HTML)
		public Response print(@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId) {
			final Writer writer = new StringWriter();
			documentContentService.htmlContent(documentId, writer);
			return Response.ok(writer.toString()).build();
		}
		
		@Path(DOCUMENT_ATTACHED_FILES)
		public AttachedFilesService attachedFilesService() {
			return attachedFilesService;
		}
		
	}
	
}
